package com.hmdp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.config.DataChainTest;
import com.hmdp.entity.BlogComments;
import com.hmdp.entity.Key;
import com.hmdp.entity.patient;
import com.hmdp.mapper.BlogCommentsMapper;
import com.hmdp.mapper.PatientMapper;
import com.hmdp.service.IPatientService;
import com.hmdp.service.IkeyService;
import com.hmdp.utils.Encryption;
import com.hmdp.utils.PatientUnit;
import com.hmdp.utils.UpperChain;
import com.hmdp.utils.UpperChainMutiQueit;
import org.junit.Test;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.*;


@Service
public class PatientServiceImpl extends ServiceImpl<PatientMapper, patient> implements IPatientService {

    @Resource
    private IkeyService keyService;

    public KeyPair rsaKeyPair;

    public  UpperChain upperChain = new UpperChain();

    public UpperChainMutiQueit upperChainMutiQueit = new UpperChainMutiQueit();

    private static final long CHAIN_INTERVAL = 30000; // 1分钟

    private Queue<patient> patientQueue = new LinkedList<>();
    private Queue<PatientUnit>patientUnitQueue = new LinkedList<>();

    Encryption encryption = new Encryption();


    @Override
    public void insert(patient p,String flag) {


        try {

            if(flag=="insert"){
                //DataChainTest dataChainTest = new DataChainTest();
                encryption = new Encryption();
                encryption.createEncry();
                String publickey = encryption.getPublicKey();
                String privatekey = encryption.getPrivateKey();
                Key key = new Key();
                key.setPatientId(p.getPatientId());
                key.setPublickey(publickey);
                key.setPrivatekey(privatekey);
                keyService.insert(key);
            }
          //实时上链
            if(p.getType()==1){
                Key key1 = keyService.queryById(p.getPatientId());
                String publickeystr = key1.getPublickey();
                ///数据加密处理
                String PatientId = String.valueOf(p.getPatientId());
                String PatientName = encryption.rsaEncrypt(p.getName(),publickeystr);
                String PatientPhone = encryption.rsaEncrypt(String.valueOf(p.getPhone()) ,publickeystr);
                String PatientPassword = encryption.rsaEncrypt(p.getPassword(),publickeystr);
                String PatientType = encryption.rsaEncrypt(String.valueOf(p.getType()),publickeystr);

                //加密上链  查询最近的一条数据
                //upperChain.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);

                //查询id对应的所有数据
                upperChainMutiQueit.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);

                queryDate(key1);
                //定时上链
            }else if(p.getType()==0){
                patientQueue.add(p);
                startChainTimer();
            }



        } catch (Exception e) {
            e.printStackTrace();
            log.error("插入患者数据出错: " + e.getMessage(), e);
            // 其他错误处理逻辑,如回滚事务、返回错误信息等
        }

    }


    //根据病人id查询，同时在区块链上查询
    @Test
    @Override
    public void queryDate(Key key) {
        String privatekey = key.getPrivatekey();
        System.out.println("私钥是： "+privatekey);
        String patientid = String.valueOf(key.getPatientId());
        try {
          //  upperChain.getPatientOrder(patientid,privatekey);
            upperChainMutiQueit.getPatientOrder(patientid,privatekey);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updatePatient(PatientUnit p,int type) {

        try{
            if(type==1){
                Key key1 = keyService.queryById(p.getId());
                String publickeystr = key1.getPublickey();
                ///数据加密处理
                String PatientId = String.valueOf(p.getId());
                String PatientName = encryption.rsaEncrypt(p.getName(),publickeystr);
                String PatientPhone = encryption.rsaEncrypt(String.valueOf(p.getPhone()) ,publickeystr);
                String PatientPassword = encryption.rsaEncrypt(p.getPassword(),publickeystr);
                String PatientType = encryption.rsaEncrypt(String.valueOf(p.getType()),publickeystr);
                //加密上链
                //upperChain.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);

                upperChainMutiQueit.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);
                queryDate(key1);
                //定时上链
            }else if(type==0){
                patientUnitQueue.add(p);
                startChainTimerUpdate();
            }
        //实时上链
        } catch (Exception e) {
                e.printStackTrace();
            }

    }








    //插入和删除，定时上链触发器
    private void startChainTimer() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                chainPatients();
            }
        }, CHAIN_INTERVAL, CHAIN_INTERVAL);
    }





    //修改数据，定时上链
    private void startChainTimerUpdate(){
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                chainPatientsUpdata();
            }
        }, CHAIN_INTERVAL, CHAIN_INTERVAL);
    }




    //插入（删除）操作数据上链
    private void chainPatients(){
        while (!patientQueue.isEmpty()){
            patient p1 = patientQueue.poll();
            Key key = keyService.queryById(p1.getPatientId());
            String publickey = key.getPublickey();
            encryption = new Encryption();
            ///数据加密处理
            String PatientId = String.valueOf(p1.getPatientId());
            try {
                String PatientName = encryption.rsaEncrypt(p1.getName(),publickey);
                String PatientPhone = encryption.rsaEncrypt(String.valueOf(p1.getPhone()) ,publickey);
                String PatientPassword = encryption.rsaEncrypt(p1.getPassword(),publickey);
                String PatientType = encryption.rsaEncrypt(String.valueOf(p1.getType()),publickey);
                //加密上链
               // upperChain.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);
                upperChainMutiQueit.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);

            } catch (Exception e) {
                e.printStackTrace();
            }
            queryDate(key);
        }
    }



    //修改操作数据上链
    private void chainPatientsUpdata(){
        while (!patientUnitQueue.isEmpty()){
            PatientUnit p1 = patientUnitQueue.poll();

            Key key = keyService.queryById(p1.getId());
            String publickey = key.getPublickey();
            encryption = new Encryption();
            ///数据加密处理
            String PatientId = String.valueOf(p1.getId());
            try {
                String PatientName = encryption.rsaEncrypt(p1.getName(),publickey);
                String PatientPhone = encryption.rsaEncrypt(p1.getPhone() ,publickey);
                String PatientPassword = encryption.rsaEncrypt(p1.getPassword(),publickey);
                String PatientType = encryption.rsaEncrypt(p1.getType(),publickey);
                //加密上链
                //upperChain.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);
                upperChainMutiQueit.addPatientOrder(PatientId,PatientName,PatientPhone,PatientPassword,PatientType);

            } catch (Exception e) {
                e.printStackTrace();
            }
            //根据病人id查询
            //            keyService.queryById(p.getPatientId());
            //            String privatekey1 = key.getPrivatekey();
            // Key key1 = keyService.queryById(p1.getPatientId());
            queryDate(key);
        }
    }


}
